package com.edu.chat.web.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.edu.buservice.util.model.TenantUtil;
import com.edu.chat.web.common.enums.ResultCodeEnum;
import com.edu.chat.web.common.model.BizException;
import com.edu.chat.web.common.model.R;
import com.edu.chat.web.config.CommonConfig;
import com.edu.chat.web.controller.vo.LibraryVO;
import com.edu.chat.web.controller.vo.PageQuery;
import com.edu.chat.web.covert.LibraryCovert;
import com.edu.chat.web.dto.LibraryInfoDTO;
import com.edu.chat.web.dto.PageResult;
import com.edu.chat.web.mapper.CsLibraryMapper;
import com.edu.chat.web.model.CsLibrary;
import com.edu.chat.web.service.CsCategoriesService;
import com.edu.chat.web.service.CsLibraryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author 86177
 * @description 针对表【cs_library(图书馆信息表)】的数据库操作Service实现
 * @createDate 2025-02-22 15:02:27
 */
@Service
@Slf4j
public class CsLibraryServiceImpl extends ServiceImpl<CsLibraryMapper, CsLibrary> implements CsLibraryService{

	@Autowired
	private CsCategoriesService csCategoriesService;

	@Override
	public R<Boolean> createLibrary(LibraryVO libraryVO) {

		if(Objects.isNull(libraryVO)){
			throw new BizException(ResultCodeEnum.PARAM_INVALID);
		}

		CsLibrary csLibrary = LibraryCovert.convert(libraryVO);

		boolean save = save(csLibrary);

		if(!save){
			throw new BizException(ResultCodeEnum.DATABASE_ERROR);
		}

		//初始化根目录
		csCategoriesService.initRootCategory(csLibrary.getId());

		return R.success(save);
	}

	@Override
	public PageResult<LibraryInfoDTO> listLibrary(PageQuery<LibraryVO> pageQuery) {

		// 参数校验
		if (Objects.isNull(pageQuery)) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "PageQuery cannot be null");
		}
		validatePageQuery(pageQuery);

		PageResult<LibraryInfoDTO> res = new PageResult<>();
		LambdaQueryWrapper<CsLibrary> queryWrapper = new LambdaQueryWrapper<>();

		// 构建查询条件
		buildQueryWrapper(queryWrapper, pageQuery.getQuery());

		// 设置排序
		queryWrapper.orderByDesc(CsLibrary::getCreatedAt);

		// 查询分页数据
		IPage<CsLibrary> pageParam = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
		IPage<CsLibrary> pageResult = page(pageParam, queryWrapper);

		// 异常处理
		if (Objects.isNull(pageResult)) {
			log.error("Database query failed for pageQuery:{}",JSONUtil.toJsonStr(pageQuery));
			throw new BizException(ResultCodeEnum.DATABASE_ERROR, "Database query failed");
		}

		// 设置分页结果
		res.setCurrentPage(pageResult.getCurrent());
		res.setTotalPages(pageResult.getPages());
		res.setTotal(pageResult.getTotal());

		// 转换数据
		List<LibraryInfoDTO> list = pageResult.getRecords().stream()
				.map(LibraryCovert::convert)
				.collect(Collectors.toList());
		res.setRecords(list);

		return res;
	}

	@Override
	@Transactional
	public R<Boolean> updateLibraryEnable(String libraryId) {

		// 先查询知识库状态
		CsLibrary csLibrary = getById(libraryId);

		if (Objects.isNull(csLibrary)) {
			log.warn("CsLibraryServiceImpl updateLibraryStatus 知识库不存在，libraryId: {}", libraryId);
			throw new BizException(ResultCodeEnum.DATA_NOT_FOUND, "知识库不存在");
		}

		Integer openSearch = csLibrary.getOpenSearch();

		// 切换状态
		csLibrary.setOpenSearch(openSearch == 1 ? 0 : 1);

		// 更新知识库状态
		boolean updateSuccess = updateById(csLibrary);

		if (!updateSuccess) {
			log.error("更新知识库状态失败，libraryId: {}", libraryId);
			throw new BizException(ResultCodeEnum.DATA_UPDATE_FAIL, "更新知识库状态失败");
		}
		return R.success(updateSuccess);

	}

	@Override
	@Transactional
	public R<Boolean> updateLibrary(LibraryVO libraryVO) {
		if(Objects.isNull(libraryVO)){
			throw new BizException(ResultCodeEnum.PARAM_INVALID);
		}
		if(Objects.isNull(libraryVO.getId())){
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "Invalid libraryId Cant not be null");
		}

		LambdaUpdateWrapper<CsLibrary> updateWrapper = new LambdaUpdateWrapper<>();

		Optional.ofNullable(libraryVO.getName()).ifPresent(name -> updateWrapper.set(CsLibrary::getTitle,name));
		Optional.ofNullable(libraryVO.getDescription()).ifPresent(description -> updateWrapper.set(CsLibrary::getDescription,description));
		Optional.ofNullable(libraryVO.getCreateBy()).ifPresent(createBy -> updateWrapper.set(CsLibrary::getCreatedBy,createBy));
		updateWrapper.eq(CsLibrary::getId, libraryVO.getId());

		updateWrapper.set(CsLibrary::getUpdatedAt,new Date());

		updateWrapper.set(CsLibrary::getUpdatedBy, StpUtil.getLoginId());
		boolean update = update(updateWrapper);

		if(!update){
			throw new BizException(ResultCodeEnum.DATABASE_ERROR, "更新知识库失败");
		}


		return R.success(Boolean.TRUE);
	}

	@Override
	public R<Boolean> deleteLibrary(String libraryId) {
		if(Objects.isNull(libraryId)){
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "Invalid libraryId Cant not be null");
		}
		if(removeById(libraryId)){
			return R.success(Boolean.TRUE);
		}
		return R.success(Boolean.FALSE);
	}

	@Override
	public List<LibraryInfoDTO> listLibraryByIds(List<String> libraryIds) {

		if(CollectionUtil.isNotEmpty(libraryIds)){
			LambdaQueryWrapper<CsLibrary> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(CsLibrary::getId,libraryIds);
			List<CsLibrary> csLibraries = list(queryWrapper);
			if(CollectionUtil.isNotEmpty(csLibraries)){
				return csLibraries.stream().map(LibraryCovert::convert).collect(Collectors.toList());
			}
		}

		return List.of();
	}



	/**
	 * 校验分页查询参数
	 */
	private void validatePageQuery(PageQuery<LibraryVO> pageQuery) {
		if (pageQuery.getPageNum() <= 0) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "Invalid pageNo: " + pageQuery.getPageNum());
		}
		if (pageQuery.getPageSize() <= 0) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "Invalid pageSize: " + pageQuery.getPageSize());
		}

	}

	/**
	 * 构建查询条件
	 */
	private void buildQueryWrapper(LambdaQueryWrapper<CsLibrary> queryWrapper, LibraryVO libraryVO) {


		if (Objects.nonNull(libraryVO)) {
			if (StringUtils.isNotBlank(libraryVO.getId())) {
				queryWrapper.eq(CsLibrary::getId, libraryVO.getId());
			}
			if (StringUtils.isNotBlank(libraryVO.getName())) {
				queryWrapper.eq(CsLibrary::getTitle, libraryVO.getName());
			}
			if (StringUtils.isNotBlank(libraryVO.getCreateBy())) {
				queryWrapper.eq(CsLibrary::getCreatedBy, libraryVO.getCreateBy());
			}
			if (Objects.nonNull(libraryVO.getEnable())) {
				queryWrapper.eq(CsLibrary::getOpenSearch, libraryVO.getEnable() ? 1 : 0);
			}

			if (Objects.nonNull(libraryVO.getPublicLibrary())){
				if (libraryVO.getPublicLibrary()){
					// 公共知识库
					TenantUtil.setCurrentTenantId(CommonConfig.PUBLIC_TENANT_ID);
				}
			}
		}
	}

}




